/***********************************************************************************************************************
 * ############################################# Application AdewebLite #############################################
 * AdewebLite Android est une application permettant de consulter des emplois du temps fournis par l'université UHP
 * avec ou sans connexion internet (informations gardées en mémoire à chaque synchronisation). Et utilisant la web
 * API ADE pour collecter les données.
 * @author Andrianjafintrimo Victor, Zanette Sébastien
 * 
 * Basée sur l'application du même nom, utilisant le flux RSS (données à traiter), de :
 * @author Schnell Michaël, Zanette Sébastien
 * **********************************************************************************************************************
 */

package ade.prime.analyzer;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

/**
 * Classe permettant de parser le flux XML récupérer grâce a la fonction
 * getEvent de l'API
 *
 * @author Zanette Sébastien, Andrianjafintrimo Victor
 */
public class ParserLesson extends DefaultHandler {
	
	private static final String TAG = ParserLesson.class.getSimpleName() ;

    // nom des tags XML
    private static final String EVENT = "event"; //$NON-NLS-1$
    private static final String RESOURCES = "resources"; //$NON-NLS-1$
    private static final String RESOURCE = "resource"; //$NON-NLS-1$
    private static final String ADDITIONAL = "additional"; //$NON-NLS-1$
    private static final String ID = "id"; //$NON-NLS-1$
    private static final String NAME = "name"; //$NON-NLS-1$
    private static final String DATE = "date"; //$NON-NLS-1$
    private static final String STARTHOUR = "startHour"; //$NON-NLS-1$
    private static final String ENDHOUR = "endHour"; //$NON-NLS-1$
    private static final String CREATION = "creation"; //$NON-NLS-1$
    private static final String UPDATE = "lastUpdate"; //$NON-NLS-1$
    private static final String COLOR = "color"; //$NON-NLS-1$
    private static final String NOTE = "note"; //$NON-NLS-1$
    private static final String CATEGORY = "category"; //$NON-NLS-1$

    private static final String COLOR_VALUES_SEPARATOR = "," ; //$NON-NLS-1$
    private static final String COLOR_FORMAT = "#%02x%02x%02x" ; //$NON-NLS-1$
    
    // Array list de feeds	
    private ArrayList<FeedLesson> feeds;
    // Boolean permettant de savoir si nous sommes � l'int�rieur d'un EVENT
    private boolean inEvent;
    // Feed courant
    private FeedLesson currentFeed;
    private FeedResources currentResources;
    private FeedResource currentResource;
    // Buffer permettant de contenir les donn�es d'un tag XML
    private StringBuffer buffer;

    /**
     * Appelle la fonction processingInstruction de la classe DefaultHandler
     * @param target
     * @param data
     * @throws SAXException
     */
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        super.processingInstruction(target, data);
    }

    /**
     * Constructeur de la classe ParserLesson
     */
    public ParserLesson() {
        super();
    }

    /**
     * Cette méthode est appelée par le parser une et une seule fois au
     * démarrage de l'analyse de votre flux xml. Elle est appelée avant toutes
     * les autres méthodes de l'interface, à l'exception unique, évidemment, de
     * la méthode setDocumentLocator. Cet évènement devrait vous permettre
     * d'initialiser tout ce qui doit l'être avant le début du parcours du
     * document.
     *
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        this.feeds = new ArrayList<FeedLesson>();

    }

    /**
     * Fonction �tant d�clench�e lorsque le parser trouve un tag XML C'est cette
     * méthode que nous allons utiliser pour instancier un nouveau feed
     *
     * @param uri
     * @param localName
     * @param name
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        // Nous réinitialisons le buffer a chaque fois qu'il rencontre un EVENT
        this.buffer = new StringBuffer();

        // Ci dessous, localName contient le nom du tag rencontré

        // Nous avons rencontré un tag EVENT, il faut donc instancier un nouveau feed
        if (localName.equalsIgnoreCase(EVENT)) {
            this.currentFeed = new FeedLesson();
            this.currentFeed.setId(attributes.getValue(ID));
            this.currentFeed.setName(attributes.getValue(NAME));
            this.currentFeed.setEndHour(attributes.getValue(ENDHOUR));
            this.currentFeed.setStartHour(attributes.getValue(STARTHOUR));
            this.currentFeed.setDate(attributes.getValue(DATE));
            this.currentFeed.setCreation(attributes.getValue(CREATION));
            this.currentFeed.setUpdate(attributes.getValue(UPDATE));
            this.currentFeed.setColor(
            		ParserLesson.parseColor(attributes.getValue(COLOR))) ;
            this.currentFeed.setNote(attributes.getValue(NOTE));
            this.inEvent = true;
        }


        // Vous pouvez d�finir des actions à effectuer pour chaque EVENT rencontré
        if (localName.equalsIgnoreCase(RESOURCES)) {
            this.currentResources = new FeedResources();
        }
        if (localName.equalsIgnoreCase(RESOURCE)) {
            this.currentResource = new FeedResource();
            this.currentResource.setId(attributes.getValue(ID));
            this.currentResource.setName(attributes.getValue(NAME));
            this.currentResource.setCategory(attributes.getValue(CATEGORY));
            this.currentResources.addResource(this.currentResource);
        }
        if (localName.equalsIgnoreCase(ADDITIONAL)) {
            // Nothing to do	
        }

    }

    /**
     * Fonction étant déclenchée lorsque le parser a parsé l'intérieur de la
     * balise XML La méthode characters a donc fait son ouvrage et tous les
     * caractère inclus dans la balise en cours sont copiés dans le buffer On
     * peut donc tranquillement les récupérer pour compléter notre objet
     * currentFeed
     *
     * @param uri
     * @param localName
     * @param name
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String name) throws SAXException {

        if (localName.equalsIgnoreCase(RESOURCES)) {
            if (this.inEvent) {
                this.currentFeed.setResources(this.currentResources);
                this.buffer = null;
            }
        }

        if (localName.equalsIgnoreCase(RESOURCE)) {
            if (this.inEvent) {
                // Les caract�res sont dans l'objet buffer
                //this.currentFeed.setRessource(this.buffer.toString());				
                this.buffer = null;
            }
        }

        if (localName.equalsIgnoreCase(ADDITIONAL)) {
            if (this.inEvent) {
                //this.currentFeed.setAddictional(this.buffer.toString());				
                this.buffer = null;
            }
        }

        if (localName.equalsIgnoreCase(EVENT)) {
//        	Log.d(TAG, ">> Lesson parsed !") ;
            this.feeds.add(this.currentFeed);
            this.inEvent = false;
        }
    }

    /**
     *  * Tout ce qui est dans l'arborescence mais n'est pas partie int�grante
     * d'un tag, d�clenche la lev�e de cet �v�nement. En g�n�ral, cet �v�nement
     * est donc lev� tout simplement par la pr�sence de texte entre la balise
     * d'ouverture et la balise de fermeture
     * @param ch
     * @param start
     * @param length
     */
    @Override
    public void characters(char[] ch, int start, int length) {
        String lecture = new String(ch, start, length);
        if (this.buffer != null) {
            this.buffer.append(lecture);
        }
    }

    /**
     * Méthode permettant de récupérer l'instance de Feed courante
     * @return 
     */
    public ArrayList<FeedLesson> getData() {
        return this.feeds;

    }
    
    protected static String parseColor(String color) {
    	String[] values = color.split(COLOR_VALUES_SEPARATOR) ;
    	
    	String result = String.format(COLOR_FORMAT, 
    			Integer.valueOf(values[0]), 
    			Integer.valueOf(values[1]), 
    			Integer.valueOf(values[2])) ;
    	
//    	Log.d("ParserLesson", String.format( //$NON-NLS-1$
//    			"[parseColor] Source: '%s', Result: '%s'", //$NON-NLS-1$
//    			color, result)) ;
    	
    	return result ;
    }// parseColor(String)
}
